TEST_PG_PORT_MASTER=5433 TEST_PG_PORT_REPLICA=5434 TEST_PG_DIR_MASTER=~/postgres_data_master TEST_PG_DIR_REPLICA=~/postgres_data_replica # Setup master mkdir $TEST_PG_DIR_MASTER pg_ctl -D $TEST_PG_DIR_MASTER initdb sed -i "s/#listen_addresses = 'localhost'/listen_addresses = '*'/g" $TEST_PG_DIR_MASTER/postgresql.conf sed -i "s/#port = 5432/port = $TEST_PG_PORT_MASTER/g" $TEST_PG_DIR_MASTER/postgresql.conf pg_ctl -D $TEST_PG_DIR_MASTER -l logfile start # Setup replica pg_basebackup -h localhost --checkpoint=fast -D $TEST_PG_DIR_REPLICA -R -X stream --port=$TEST_PG_PORT_MASTER sed -i "s/#listen_addresses = 'localhost'/listen_addresses = '*'/g" $TEST_PG_DIR_REPLICA/postgresql.conf sed -i "s/port = $TEST_PG_PORT_MASTER/port = $TEST_PG_PORT_REPLICA/g" $TEST_PG_DIR_REPLICA/postgresql.conf pg_ctl -D $TEST_PG_DIR_REPLICA -l logfile_replica start # Check replication is working psql postgres --port=$TEST_PG_PORT_MASTER -c " create table t ( a integer, b text, d timestamp without time zone ); insert into t select i, 'test-master-2-replica'||i , now() from generate_series(1, 5)i; " sleep 2 psql postgres --port=$TEST_PG_PORT_REPLICA -c "select * from t;"; # Shutdown master and switch to replica pg_ctl -D $TEST_PG_DIR_MASTER stop # enable test changes that will postpone CreateEndOfRecoveryRecord() touch $TEST_PG_DIR_REPLICA/delay_recovery.signal psql postgres --port=$TEST_PG_PORT_REPLICA -c "SELECT pg_promote();" & # Shutdown immediately Postgres (in real life that could be an accident power loss, or any other system level problem...) sleep 5 # sleep a while to ensure that history file was created pg_ctl -D $TEST_PG_DIR_REPLICA stop -m i sleep 5 # cleanup - we do not need the file anymore rm $TEST_PG_DIR_REPLICA/delay_recovery.signal # start replica again pg_ctl -D $TEST_PG_DIR_REPLICA -l logfile_replica start # after this point replica is started, and working, but the timeline is still 1 !!! # it can be checked with `pg_controldata $TEST_PG_DIR_REPLICA` # and we will get problems later once we switch the replica back to its original role (refer to steps below). # Bring back master as replica touch $TEST_PG_DIR_MASTER/standby.signal sed -i "s/#primary_conninfo = ''/primary_conninfo = 'host=localhost port=$TEST_PG_PORT_REPLICA'/g" $TEST_PG_DIR_MASTER/postgresql.conf pg_ctl -D $TEST_PG_DIR_MASTER -l logfile start # Check replication is working psql postgres --port=$TEST_PG_PORT_REPLICA -c " create table t2 ( a integer, b text, d timestamp without time zone ); insert into t2 select i, 'test-replica-2-master'||i , now() from generate_series(1, 5)i; " sleep 2 psql postgres --port=$TEST_PG_PORT_MASTER -c "select * from t2;"; # Switch back pg_ctl -D $TEST_PG_DIR_REPLICA stop psql postgres --port=$TEST_PG_PORT_MASTER -c "SELECT pg_promote();" touch $TEST_PG_DIR_REPLICA/standby.signal pg_ctl -D $TEST_PG_DIR_REPLICA -l logfile_replica start # attempt to start replica here will result in: # 'pg_ctl: could not start server' # 'Examine the log output.' # and in the log: # 2025-01-16 17:30:27.174 +10 [4806] FATAL: requested timeline 2 is not a child of this server's history # 2025-01-16 17:30:27.174 +10 [4806] DETAIL: Latest checkpoint is at 0/303FF90 on timeline 1, but in the history of the requested timeline, the server forked off from that timeline at 0/3023538. #